﻿//代表的是多对一的关联（关联类是站在主-从关系去封装model间的关系的）
Ext.data.BelongsToAssociation = Ext.extend(Ext.data.Association, {

    constructor: function (config) {
        Ext.data.BelongsToAssociation.superclass.constructor.apply(this, arguments);

        var me = this,
            ownerProto = me.ownerModel.prototype,                //主model的原型对象
            associatedName = me.associatedName,                  //从model的注册名
            getterName = me.getterName || 'get' + associatedName,//获取从model的方法名称
            setterName = me.setterName || 'set' + associatedName;//设置从model的方法名称

        Ext.applyIf(me, {
            name: associatedName,//从model名称
            foreignKey: associatedName.toLowerCase() + "_id",//代表外键
            instanceName: associatedName + 'BelongsToInstance'//代表关联方式
        });

        ownerProto[getterName] = me.createGetter();// 从model加载数据
        ownerProto[setterName] = me.createSetter(); //保存从模型的数据到数据源的方法
    },

    //保存从模型的数据到数据源的方法
    createSetter: function () {
        var me = this,
            ownerModel = me.ownerModel,          //主model
            associatedModel = me.associatedModel,//从model
            foreignKey = me.foreignKey,          //外键
            primaryKey = me.primaryKey;          //主键

        //value：外键对应的值
        //options：回调函数
        //scope：作用域
        return function (value, options, scope) {
            this.set(foreignKey, value);//调用者使用自身的set方法将外键和值对应（调用者毫无疑问是一个model，它的set方法是从Ext.data.Stateful中继承过来的）

            if (typeof options == 'function') {
                options = {
                    callback: options,
                    scope: scope || this
                };
            }

            // 保存从模型的数据到数据源
            if (Ext.isObject(options)) {
                return this.save(options); //调用者使用自身的save方法（调用者毫无疑问是一个model)
            }
        };
    },

    // 从model加载数据
    createGetter: function () {
        var me = this,
            ownerModel = me.ownerModel,
            associatedName = me.associatedName,
            associatedModel = me.associatedModel,
            foreignKey = me.foreignKey,
            primaryKey = me.primaryKey,
            instanceName = me.instanceName;


        return function (options, scope) {
            options = options || {};

            var foreignKeyId = this.get(foreignKey),
                instance, callbackFn;

            // 如果还没创建实例对象
            if (this[instanceName] == undefined) {
                instance = Ext.ModelMgr.create({}, associatedName); // 创建从model的实例对象
                instance.set(primaryKey, foreignKeyId); // 记录的主键即为外建对应的值

                if (typeof options == 'function') {
                    options = {
                        callback: options,
                        scope: scope || this
                    };
                }

                associatedModel.load(foreignKeyId, options); // 从model加载数据
            } else {
                instance = this[instanceName];



                // 直接获取存储中的数据
                if (typeof options == 'function') {
                    options.call(scope || this, instance);
                }

                if (options.success) {
                    options.success.call(scope || this, instance);
                }

                if (options.callback) {
                    options.callback.call(scope || this, instance);
                }

                return instance;
            }
        };
    }
});